home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1997 February / EnigmA AMIGA RUN 15 (1997)(G.R. Edizioni)(IT)[!][issue 1997-02][PLANET CD V].iso / enigma / earcd / utility / utilgraf / newicndt.lha / NewIconDT / Sources / dispatch.c < prev    next >
C/C++ Source or Header  |  1996-10-25  |  21KB  |  774 lines

  1. //;--T--T--T--T--T--T--T--T--T--T--T--T--T--T--T--T--T--T--T--T--T--T--T--T--T--T--T
  2. /******************************************************************************
  3.  *
  4.  * NewIcon Datatype
  5.  *
  6.  * Written by Pascal Hurni and Christian Buchner and David N. Junod
  7.  *
  8.  ******************************************************************************
  9.  * dispatch.c
  10.  *
  11.  */
  12.  
  13. /************************************************************************
  14.  *                                                                                                *
  15.  *    Prefs:                                                                                    *
  16.  *        NOBORDER/S        Dont' draw the border around images.                    *
  17.  *        NONORMAL/S        Dont' include the normal state image.                    *
  18.  *        NOSELECTED/S    Dont' include the selected state image.                *
  19.  *        XOFFSET/N        Defines the number of pixels between the horizontal*
  20.  *                            borders and the images. Default to 2.                    *
  21.  *        YOFFSET/N        Defines the number of pixels between the vertical    *
  22.  *                            borders and the images. Default to 2.                    *
  23.  *        BORDERPEN/N        The pen number used to draw the border. Default        *
  24.  *                            to 1.                                                                *
  25.  *        COLORMAP            A picture filename containing a colormap. The        *
  26.  *                            images will be remaped to this colormap.                *
  27.  *                                                                                                *
  28.  ************************************************************************/
  29.  
  30.  
  31. //#define DEBUG
  32. #include "debug.h"
  33. #include "classbase.h"
  34.  
  35. /*****************************************************************************/
  36.  
  37. void MineWriteChunkyPixels( struct RastPort *rp, LONG xstart, LONG ystart,
  38.                             LONG xstop, LONG ystop, UBYTE *array, LONG bytesperrow,
  39.                             UBYTE *convtable, LONG flags,
  40.                             struct ClassBase *cb );
  41.  
  42. UBYTE MyObtainBestPen( struct ColorRegister color, struct ColorRegister *cmap,
  43.                        UWORD ncol );
  44.  
  45. Object *GetFileColorMap( STRPTR filename, struct ColorRegister **pt_cmap, ULONG *pt_ncolors,
  46.                          struct ClassBase *cb );
  47. void FreeFileColorMap( Object *obj, struct ClassBase *cb );
  48.  
  49.  
  50. #define PREFSTEMPLATE    "NOBORDER/S,NONORMAL/S,NOSELECTED/S,XOFFSET/N,YOFFSET/N,BORDERPEN/N,COLORMAP"
  51.  
  52. enum {
  53.     PREFSARG_NOBORDER,
  54.     PREFSARG_NONORMAL,
  55.     PREFSARG_NOSELECTED,
  56.     PREFSARG_XOFFSET,
  57.     PREFSARG_YOFFSET,
  58.     PREFSARG_BORDERPEN,
  59.     PREFSARG_COLORMAP,
  60.     PREFSARG_MAX
  61. };
  62.  
  63. /*****************************************************************************/
  64.  
  65. ULONG setdtattrs (struct ClassBase * cb, Object * o, ULONG data,...)
  66. {
  67.     return (SetDTAttrsA (o, NULL, NULL, (struct TagItem *) & data));
  68. }
  69.  
  70. /*****************************************************************************/
  71.  
  72. ULONG getdtattrs (struct ClassBase * cb, Object * o, ULONG data,...)
  73. {
  74.     return (GetDTAttrsA (o, (struct TagItem *) & data));
  75. }
  76.  
  77. /*****************************************************************************/
  78.  
  79. Class *initClass (struct ClassBase * cb)
  80. {
  81.     Class *cl;
  82.     
  83.     /* Create our class.  Note that this particular class doesn't have any instance data */
  84.     if (cl = MakeClass (NEWICONDTCLASS, PICTUREDTCLASS, NULL, NULL, 0L))
  85.     {
  86.         cl->cl_Dispatcher.h_Entry = (ULONG (*)())Dispatch;
  87.         cl->cl_UserData = (ULONG) cb;
  88.         AddClass (cl);
  89.     }
  90.     
  91.     return (cl);
  92. }
  93.  
  94. /*****************************************************************************/
  95.  
  96. ULONG __asm Dispatch (register __a0 Class * cl, register __a2 Object * o, register __a1 Msg msg)
  97. {
  98.     struct ClassBase *cb = (struct ClassBase *) cl->cl_UserData;
  99.     ULONG retval;
  100.     
  101.     switch (msg->MethodID)
  102.     {
  103.         case OM_NEW:
  104.         if (retval = DoSuperMethodA (cl, o, msg))
  105.         {
  106.             if (!GetPicture (cb, cl, (Object *) retval, ((struct opSet *) msg)->ops_AttrList))
  107.             {
  108.                 CoerceMethod (cl, (Object *) retval, OM_DISPOSE);
  109.                 return NULL;
  110.             }
  111.         }
  112.         break;
  113.         
  114.         /* Let the superclass handle everything else */
  115.         default:
  116.         retval = (ULONG) DoSuperMethodA (cl, o, msg);
  117.         break;
  118.     }
  119.     
  120.     return (retval);
  121. }
  122.  
  123. /*****************************************************************************/
  124.  
  125. BOOL __asm GetPicture (register __a6 struct ClassBase * cb, register __a0 Class * cl, register __a2 Object * o, register __a1 struct TagItem * attrs)
  126. {
  127.     BOOL                        success = FALSE;
  128.     STRPTR                    title;
  129.     STRPTR                    fname;
  130.     struct BitMapHeader    *bmhd;
  131.     struct BitMap            *bm;
  132.     UWORD                        i, n, ncolors;
  133.     ULONG                        modeid = VGAPRODUCT_KEY;
  134.     struct ColorRegister    *cmap, *tmpcmap;
  135.     LONG                        *cregs;
  136.  
  137.     ULONG                        TmpOffset;
  138.     ULONG                        XOffset = 2;
  139.     ULONG                        YOffset = 2;
  140.     UWORD                        BorderPen = 1;
  141.  
  142.     struct NewDiskObject    *ndo;
  143.     ULONG                        depth, rest;
  144.     STRPTR                    tmp;
  145.  
  146.     struct RastPort        rp;
  147.     Point                        PolyDrawArray[4];
  148.     UBYTE                        *ConvTable;
  149.  
  150.     Object                    *obj;
  151.     BPTR                        fh;
  152.     struct ColorRegister    *var_ColorMap = NULL;
  153.     ULONG                        var_NColors;
  154.     ULONG                        var_Border   = TRUE;
  155.     ULONG                        var_Normal   = TRUE;
  156.     ULONG                        var_Selected = TRUE;
  157.  
  158.  
  159.     ENTERING;
  160.  
  161.  
  162.     /* Get the default title */
  163.     title = (STRPTR) GetTagData (DTA_Name, NULL, attrs);
  164.  
  165.     /* create the filename */
  166.  
  167.     if ( !(fname = AllocVec( strlen( title ) , 0L ) ) ) {
  168.         SetIoErr(ERROR_NO_FREE_STORE);
  169.     }
  170.     else {
  171.  
  172.         strcpy( fname, title );
  173.  
  174.         if ( !((tmp = strrchr( fname, '.' )) && (strcmp( tmp, ".info" ) == 0)) ) {
  175.             SetIoErr(ERROR_INVALID_COMPONENT_NAME);
  176.         }
  177.         else {
  178.  
  179.         *tmp = 0;
  180.  
  181.     
  182.         /* Get the BitMapHeader to write to */
  183.         if ( getdtattrs (cb, o, PDTA_BitMapHeader, &bmhd, TAG_DONE) != 1 )
  184.         {
  185.             SetIoErr(ERROR_OBJECT_WRONG_TYPE);
  186.         }
  187.         else
  188.         {
  189.  
  190.  
  191.             DPUT(("About to get prefs vars.\n" ));
  192.  
  193.             /*** Get the environement variables for the preferences */
  194.  
  195.             /* Opens the prefs file */
  196.             if ( fh = Open( "ENV:Datatypes/NewIcon.prefs", MODE_OLDFILE ) ) {
  197.  
  198.                 struct RDArgs *rdargs;
  199.                 UBYTE buf[256];
  200.                 ULONG para[PREFSARG_MAX];
  201.  
  202.                 DPUT(("Prefs file opened.\n" ));
  203.  
  204.                 /* Get next line */
  205.                 while ( FGets( fh, buf, sizeof(buf) ) ) {
  206.  
  207.                     /* Process it if it's not a comment */
  208.                     tmp = buf;
  209.                     while ( *tmp < 33 && *tmp != 0 ) tmp++;
  210.                     if ( !((*tmp == ';') || (*tmp == '#') || (*tmp == '*') || (*tmp == 0)) ) {
  211.  
  212.                         if ( rdargs = (struct RDArgs *)AllocDosObject( DOS_RDARGS, NULL ) ) {
  213.  
  214.                             rdargs->RDA_Source.CS_Buffer = buf;
  215.                             rdargs->RDA_Source.CS_Length = strlen(buf);
  216.  
  217.                             para[PREFSARG_NOBORDER]        = FALSE;
  218.                             para[PREFSARG_NONORMAL]        = FALSE;
  219.                             para[PREFSARG_NOSELECTED]    = FALSE;
  220.                             para[PREFSARG_XOFFSET]        = NULL;
  221.                             para[PREFSARG_YOFFSET]        = NULL;
  222.                             para[PREFSARG_BORDERPEN]    = NULL;
  223.                             para[PREFSARG_COLORMAP]        = NULL;
  224.  
  225.                             if ( ReadArgs( PREFSTEMPLATE, (LONG *) para, rdargs) ) {
  226.  
  227.                                 if ( para[PREFSARG_NOBORDER] )
  228.                                     var_Border = FALSE;
  229.  
  230.                                 if ( para[PREFSARG_NONORMAL] )
  231.                                     var_Normal = FALSE;
  232.  
  233.                                 if ( para[PREFSARG_NOSELECTED] )
  234.                                     var_Selected = FALSE;
  235.  
  236.                                 if ( para[PREFSARG_XOFFSET] ) {
  237.                                     XOffset = *((LONG *) para[PREFSARG_XOFFSET]);
  238.                                     if ( XOffset > 65535 ) XOffset = 2;
  239.                                 }
  240.  
  241.                                 if ( para[PREFSARG_YOFFSET] ) {
  242.                                     YOffset = *((LONG *) para[PREFSARG_YOFFSET]);
  243.                                     if ( YOffset > 65535 ) YOffset = 2;
  244.                                 }
  245.  
  246.                                 if ( para[PREFSARG_BORDERPEN] ) {
  247.                                     BorderPen = (*((LONG *) para[PREFSARG_BORDERPEN])) & 255;
  248.                                 }
  249.  
  250.                                 if ( para[PREFSARG_COLORMAP] ) {
  251.                                     obj = GetFileColorMap( (STRPTR)para[PREFSARG_COLORMAP], &var_ColorMap, &var_NColors, cb );
  252.                                 }
  253.  
  254.                             }
  255.  
  256.                             FreeDosObject( DOS_RDARGS, rdargs );
  257.  
  258.                         }
  259.  
  260.                     }
  261.  
  262.                 }
  263.  
  264.                 Close( fh );
  265.  
  266.             }
  267.  
  268.  
  269.             DPUT(("About to GetNewDiskObject() with fname=[%s]\n", fname ));
  270.  
  271.             if ( ndo = GetNewDiskObject( fname ) ) {
  272.  
  273.                 DPUT(("GetNewDiskObject() successful !\n" ));
  274.  
  275.                 if ( (ndo->ndo_NormalImage != NULL && var_Normal) || (ndo->ndo_SelectedImage != NULL && var_Selected) ) {
  276.  
  277.  
  278.                     /*** Computes the BitMap dimensions */
  279.  
  280.                     bmhd->bmh_Width = XOffset;
  281.                     bmhd->bmh_Height = 0;
  282.  
  283.                     if ( ndo->ndo_NormalImage && var_Normal ) {
  284.                         bmhd->bmh_Width += ndo->ndo_NormalImage->Width+XOffset;
  285.                         bmhd->bmh_Height = ndo->ndo_NormalImage->Height;
  286.                         if ( var_Border )
  287.                             bmhd->bmh_Width += 1+1;
  288.  
  289.                         DPUT(("NormalImage: Width=%ld, Height=%ld\n", (LONG)ndo->ndo_NormalImage->Width, (LONG)ndo->ndo_NormalImage->Height ));
  290.                     }
  291.  
  292.                     if ( ndo->ndo_SelectedImage && var_Selected ) {
  293.                         bmhd->bmh_Width += ndo->ndo_SelectedImage->Width+XOffset;
  294.                         bmhd->bmh_Height = MAX( ndo->ndo_NormalImage->Height, bmhd->bmh_Height );
  295.                         if ( var_Border )
  296.                             bmhd->bmh_Width += 1+1;
  297.  
  298.                         DPUT(("SelectedImage: Width=%ld, Height=%ld\n", (LONG)ndo->ndo_SelectedImage->Width, (LONG)ndo->ndo_SelectedImage->Height ));
  299.                     }
  300.  
  301.                     bmhd->bmh_Height += YOffset+YOffset;
  302.                     if ( var_Border )
  303.                         bmhd->bmh_Height += 1+1;
  304.  
  305.  
  306.                     /*** Get the number of different colors in both image */
  307.  
  308.                     if ( var_ColorMap ) {
  309.  
  310.                         ncolors = var_NColors;
  311.  
  312.                     }
  313.                     else {
  314.  
  315.                         if ( !ndo->ndo_NormalImage || !var_Normal ) {
  316.                             ncolors = ndo->ndo_SelectedImage->NumColors;
  317.                         }
  318.                         else if ( !ndo->ndo_SelectedImage || !var_Selected ) {
  319.                             ncolors = ndo->ndo_NormalImage->NumColors;
  320.                         }
  321.                         else {
  322.  
  323.                             ncolors = ndo->ndo_NormalImage->NumColors;
  324.  
  325.                             for ( n=0; n<ndo->ndo_SelectedImage->NumColors; n++ ) {
  326.  
  327.                                 for ( i=0; i<ndo->ndo_NormalImage->NumColors; i++ ) {
  328.                                     if ( *((struct ColorRegister *) &(ndo->ndo_NormalImage->Palette[i*3])) ==
  329.                                          *((struct ColorRegister *) &(ndo->ndo_SelectedImage->Palette[n*3])) ) {
  330.  
  331.                                         ncolors--;
  332.                                         break;
  333.                                     }
  334.  
  335.                                 }
  336.  
  337.                                 ncolors++;
  338.  
  339.                             }
  340.  
  341.                         }
  342.  
  343.                     }
  344.  
  345.                     /*** Calculate the depth according to ncolors */
  346.  
  347.                     depth = 0;
  348.                     rest = ncolors-1;
  349.                     while ( rest > 0 ) {
  350.                         rest = rest >> 1;
  351.                         depth++;
  352.                     }
  353.                     if ( depth == 0 ) depth = 1;    /*** If ncolors was 1 */
  354.                     if ( depth > 8 ) {
  355.                         depth = 8;    /*** If ncolors was greater than 256 */
  356.                         ncolors = 256;
  357.                     }
  358.  
  359.                     bmhd->bmh_Depth = depth;
  360.  
  361.  
  362.                     DPUT(("BMHD: Width=%ld, Height=%ld, NColors=%ld, Depth=%ld\n",
  363.                         (LONG)bmhd->bmh_Width, (LONG)bmhd->bmh_Height, (LONG)ncolors, (LONG)bmhd->bmh_Depth ));
  364.  
  365.                     /* Set the number of colors */
  366.                     setdtattrs (cb, o, PDTA_NumColors, ncolors, TAG_DONE);
  367.             
  368.                     /* Get the destination for the color information */
  369.                     getdtattrs (cb, o,
  370.                                     PDTA_ColorRegisters,    (ULONG) &cmap,
  371.                                     PDTA_CRegs,                &cregs,
  372.                                     TAG_DONE);
  373.  
  374.  
  375.                     /*** Set up the Colormap for both images */
  376.  
  377.                     if ( var_ColorMap ) {
  378.  
  379.                         DPUT(("The ColorMap :"));
  380.  
  381.                         tmpcmap = cmap;
  382.  
  383.                         for ( n=0; n<ncolors; n++ ) {
  384.  
  385.                             /* Set the master color table */
  386.                             tmpcmap->red   = var_ColorMap->red;
  387.                             tmpcmap->green = var_ColorMap->green;
  388.                             tmpcmap->blue  = var_ColorMap->blue;
  389.  
  390.                             /* Set the color table used for remapping */
  391.                             cregs[n * 3 + 0] = tmpcmap->red   << 24;
  392.                             cregs[n * 3 + 1] = tmpcmap->green << 24;
  393.                             cregs[n * 3 + 2] = tmpcmap->blue  << 24;
  394.  
  395.                             D(if ( (n % 8) == 0 ) bprintf("\n") );
  396.                             DPUT(("%02lx%02lx%02lx ", (LONG) tmpcmap->red, (LONG) tmpcmap->green, (LONG) tmpcmap->blue ));
  397.  
  398.                             tmpcmap++;
  399.                             var_ColorMap++;
  400.                         }
  401.  
  402.                         DPUT(("\n\n"));
  403.  
  404.                         /*** Frees the file colormap */
  405.                         FreeFileColorMap( obj, cb );
  406.  
  407.                     }
  408.                     else {
  409.  
  410.                         if ( !ndo->ndo_NormalImage ) {
  411.                             memcpy( cmap, ndo->ndo_SelectedImage->Palette, ndo->ndo_SelectedImage->NumColors * 3 );
  412.                         }
  413.                         else if ( !ndo->ndo_SelectedImage ) {
  414.                             memcpy( cmap, ndo->ndo_NormalImage->Palette, ndo->ndo_NormalImage->NumColors * 3 );
  415.                         }
  416.                         else {
  417.  
  418.                             memcpy( cmap, ndo->ndo_NormalImage->Palette, ndo->ndo_NormalImage->NumColors * 3 );
  419.  
  420.                             tmpcmap = cmap+ndo->ndo_NormalImage->NumColors;
  421.  
  422.                             /*** BUG: It can happen that NormalImage->NumColors plus the different
  423.                              *** colors in SelectedImage could exceeds 256 ! A check should be done
  424.                              *** inside the for loop below.
  425.                              **/
  426.  
  427.                             for ( n=0; n<ndo->ndo_SelectedImage->NumColors; n++ ) {
  428.  
  429.                                 for ( i=0; i<ndo->ndo_NormalImage->NumColors; i++ ) {
  430.                                     if ( *((struct ColorRegister *) &(ndo->ndo_NormalImage->Palette[i*3])) ==
  431.                                          *((struct ColorRegister *) &(ndo->ndo_SelectedImage->Palette[n*3])) ) {
  432.                                         break;
  433.                                     }
  434.  
  435.                                 }
  436.  
  437.                                 if ( i == ndo->ndo_NormalImage->NumColors ) {
  438.                                     *tmpcmap = *((struct ColorRegister *) &(ndo->ndo_SelectedImage->Palette[n*3]));
  439.                                     tmpcmap++;
  440.                                 }
  441.  
  442.                             }
  443.  
  444.                         }
  445.  
  446.                         DPUT(("The ColorMap :"));
  447.  
  448.                         tmpcmap = cmap;
  449.  
  450.                         for ( n=0; n<ncolors; n++ ) {
  451.  
  452.                             D(if ( (n % 8) == 0 ) bprintf("\n") );
  453.                             DPUT(("%02lx%02lx%02lx ", (LONG) tmpcmap->red, (LONG) tmpcmap->green, (LONG) tmpcmap->blue ));
  454.  
  455.                             /* Set the color table used for remapping */
  456.                             cregs[n * 3 + 0] = tmpcmap->red   << 24;
  457.                             cregs[n * 3 + 1] = tmpcmap->green << 24;
  458.                             cregs[n * 3 + 2] = tmpcmap->blue  << 24;
  459.  
  460.                             tmpcmap++;
  461.                         }
  462.  
  463.                         DPUT(("\n\n"));
  464.  
  465.                     }
  466.  
  467.  
  468.                     /* Allocate the bitmap and the memory for the convtable */
  469.                     if ( ( (bm = AllocBitMap (bmhd->bmh_Width, bmhd->bmh_Height, bmhd->bmh_Depth, BMF_CLEAR, NULL)) == NULL ) ||
  470.                          ( (ConvTable = AllocVec( ncolors, 0L ) ) == NULL ) ) {
  471.                         FreeBitMap( bm );
  472.                         FreeVec( ConvTable );
  473.                         SetIoErr (ERROR_NO_FREE_STORE);
  474.                     }
  475.                     else
  476.                     {
  477.                         /* Indicate success */
  478.                         success = TRUE;
  479.  
  480.  
  481.                         /*** Set up the RastPort */
  482.  
  483.                         InitRastPort( &rp );
  484.                         rp.BitMap = bm;
  485.  
  486.  
  487.                         if ( ndo->ndo_NormalImage && var_Normal ) {
  488.  
  489.  
  490.                             if ( var_Border ) {
  491.                                 /*** Draws the border for the Normal image */
  492.  
  493.                                 SetAPen( &rp, BorderPen );
  494.                                 Move( &rp, XOffset, YOffset );
  495.                                 PolyDrawArray[0].x = XOffset+ndo->ndo_NormalImage->Width+1;
  496.                                 PolyDrawArray[0].y = YOffset;
  497.                                 PolyDrawArray[1].x = XOffset+ndo->ndo_NormalImage->Width+1;
  498.                                 PolyDrawArray[1].y = YOffset+ndo->ndo_NormalImage->Height+1;
  499.                                 PolyDrawArray[2].x = XOffset;
  500.                                 PolyDrawArray[2].y = YOffset+ndo->ndo_NormalImage->Height+1;
  501.                                 PolyDrawArray[3].x = XOffset;
  502.                                 PolyDrawArray[3].y = YOffset;
  503.                                 PolyDraw( &rp, 4, (WORD *)PolyDrawArray );
  504.                             }
  505.  
  506.                             /*** Computes the ConvTable for the Normal image */
  507.  
  508.                             DPUT(("ConvTable for Normal image\n"));
  509.  
  510.                             for ( i=0; i<ndo->ndo_NormalImage->NumColors; i++ ) {
  511.  
  512.                                 ConvTable[i] = MyObtainBestPen( *((struct ColorRegister *) &(ndo->ndo_NormalImage->Palette[i*3])),
  513.                                                                 cmap, ncolors );
  514.  
  515.                                 DPUT(("ConvTable[%ld] = %ld for color = %02lx%02lx%02lx\n",
  516.                                     (LONG) i, (LONG) ConvTable[i],
  517.                                     (LONG) ndo->ndo_NormalImage->Palette[i*3],
  518.                                     (LONG) ndo->ndo_NormalImage->Palette[i*3+1],
  519.                                     (LONG) ndo->ndo_NormalImage->Palette[i*3+2] ));
  520.  
  521.                             }
  522.  
  523.  
  524.                             /*** Copy the Normal image */
  525.  
  526.                             if ( !var_Border ) {
  527.                                 XOffset--;
  528.                                 YOffset--;
  529.                             }
  530.                             MineWriteChunkyPixels( &rp, XOffset+1, YOffset+1,
  531.                                                    XOffset+ndo->ndo_NormalImage->Width,
  532.                                                    YOffset+ndo->ndo_NormalImage->Height,
  533.                                                    ndo->ndo_NormalImage->ChunkyData,
  534.                                                    ndo->ndo_NormalImage->Width,
  535.                                                    ConvTable,
  536.                                                    ndo->ndo_NormalImage->Flags,
  537.                                                    cb );
  538.                             if ( !var_Border ) {
  539.                                 XOffset++;
  540.                                 YOffset++;
  541.                             }
  542.  
  543.                             TmpOffset = XOffset+ndo->ndo_NormalImage->Width+XOffset;
  544.                             if ( var_Border )
  545.                                 TmpOffset += 2;
  546.  
  547.  
  548.                         }
  549.                         else {
  550.  
  551.                             TmpOffset = XOffset;
  552.  
  553.                         }
  554.  
  555.  
  556.                         if ( ndo->ndo_SelectedImage && var_Selected ) {
  557.  
  558.                             if ( var_Border ) {
  559.                                 /*** Draws the border for the Selected image */
  560.  
  561.                                 SetAPen( &rp, BorderPen );
  562.                                 Move( &rp, TmpOffset, YOffset );
  563.                                 PolyDrawArray[0].x = TmpOffset+ndo->ndo_SelectedImage->Width+1;
  564.                                 PolyDrawArray[0].y = YOffset;
  565.                                 PolyDrawArray[1].x = TmpOffset+ndo->ndo_SelectedImage->Width+1;
  566.                                 PolyDrawArray[1].y = YOffset+ndo->ndo_SelectedImage->Height+1;
  567.                                 PolyDrawArray[2].x = TmpOffset;
  568.                                 PolyDrawArray[2].y = YOffset+ndo->ndo_SelectedImage->Height+1;
  569.                                 PolyDrawArray[3].x = TmpOffset;
  570.                                 PolyDrawArray[3].y = YOffset;
  571.                                 PolyDraw( &rp, 4, (WORD *)PolyDrawArray );
  572.  
  573.                             }
  574.  
  575.                             /*** Computes the ConvTable for the Selected image */
  576.  
  577.                             DPUT(("\nConvTable for Selected image\n"));
  578.  
  579.                             for ( i=0; i<ndo->ndo_SelectedImage->NumColors; i++ ) {
  580.  
  581.                                 ConvTable[i] = MyObtainBestPen( *((struct ColorRegister *) &(ndo->ndo_SelectedImage->Palette[i*3])),
  582.                                                                 cmap, ncolors );
  583.                                 DPUT(("ConvTable[%ld] = %ld for color = %02lx%02lx%02lx\n",
  584.                                     (LONG) i, (LONG) ConvTable[i],
  585.                                     (LONG) ndo->ndo_SelectedImage->Palette[i*3],
  586.                                     (LONG) ndo->ndo_SelectedImage->Palette[i*3+1],
  587.                                     (LONG) ndo->ndo_SelectedImage->Palette[i*3+2] ));
  588.  
  589.                             }
  590.  
  591.  
  592.                             /*** Copy the Selected image */
  593.  
  594.                             if ( !var_Border ) {
  595.                                 TmpOffset--;
  596.                                 YOffset--;
  597.                             }
  598.                             MineWriteChunkyPixels( &rp, TmpOffset+1, YOffset+1,
  599.                                                    TmpOffset+ndo->ndo_SelectedImage->Width,
  600.                                                    YOffset+ndo->ndo_SelectedImage->Height,
  601.                                                    ndo->ndo_SelectedImage->ChunkyData,
  602.                                                    ndo->ndo_SelectedImage->Width,
  603.                                                    ConvTable,
  604.                                                    ndo->ndo_SelectedImage->Flags,
  605.                                                    cb );
  606.  
  607.                         }
  608.  
  609.  
  610.                         if (success)
  611.                         {
  612.                             /* Set the attributes */
  613.                             setdtattrs (cb, o,
  614.                                 DTA_ObjName,        title,
  615.                                 DTA_NominalHoriz,    bmhd->bmh_Width,
  616.                                 DTA_NominalVert,    bmhd->bmh_Height,
  617.                                 GA_Width,            bmhd->bmh_Width,
  618.                                 GA_Height,            bmhd->bmh_Height,
  619.                                 PDTA_BitMap,        bm,
  620.                                 PDTA_ModeID,        modeid,
  621.                                 TAG_DONE);
  622.                         }
  623.                         else
  624.                         {
  625.                             /* Free the bitmap on failure */
  626.                             FreeBitMap(bm);
  627.                         }
  628.  
  629.                         FreeVec( ConvTable );
  630.  
  631.                     }
  632.  
  633.                 }
  634.  
  635.                 FreeNewDiskObject( ndo );
  636.  
  637.             }
  638.  
  639.         }
  640.  
  641.         }
  642.  
  643.         FreeVec( fname );
  644.  
  645.     }
  646.  
  647.  
  648.     DPUT(("\nReturning with success=%ld\n", (LONG)success));
  649.  
  650.     LEAVING;
  651.  
  652.     return (success);
  653.  
  654. }
  655.  
  656. /*****************************************************************************/
  657.  
  658. void MineWriteChunkyPixels( struct RastPort *rp, LONG xstart, LONG ystart,
  659.                             LONG xstop, LONG ystop, UBYTE *array, LONG bytesperrow,
  660.                             UBYTE *convtable, LONG flags,
  661.                             struct ClassBase *cb ) {
  662.  
  663.     /* Actually, bytesperrow is ignored */
  664.  
  665.     LONG        x,y;
  666.  
  667.  
  668.     for ( y=ystart; y<=ystop; y++ ) {
  669.  
  670.         for ( x=xstart; x<=xstop; x++ ) {
  671.  
  672.             SetAPen( rp, convtable[*array++] );
  673.             WritePixel( rp, x, y );
  674.  
  675.         }
  676.  
  677.     }
  678.  
  679. }
  680.  
  681. /*****************************************************************************/
  682.  
  683. UBYTE MyObtainBestPen( struct ColorRegister color, struct ColorRegister *cmap,
  684.                        UWORD ncol ) {
  685.  
  686.     UWORD            red, green, blue;
  687.     UWORD            i;
  688.     UWORD            pen;
  689.     UWORD            prox;
  690.     UWORD            oldprox = 0xFFFF;
  691.  
  692.     red   = color.red   << 4;
  693.     green = color.green << 4;
  694.     blue  = color.blue  << 4;
  695.  
  696.  
  697.     for ( i=0; i<ncol; i++ ) {
  698.  
  699.         if ( (prox = TestProximity( cmap->red << 4 , cmap->green << 4 , cmap->blue << 4 ,
  700.                                     red, green, blue ) ) == 0 ) {
  701.             return (UBYTE)i;
  702.         }
  703.  
  704.         if ( prox < oldprox ) {
  705.             oldprox = prox;
  706.             pen = i;
  707.         }
  708.  
  709.         cmap++;
  710.  
  711.     }
  712.  
  713.     return (UBYTE)pen;
  714.  
  715. }
  716.  
  717. /*****************************************************************************/
  718.  
  719. Object *GetFileColorMap( STRPTR filename, struct ColorRegister **pt_cmap, ULONG *pt_ncolors,
  720.                          struct ClassBase *cb ) {
  721.  
  722.     struct DataType    *dt;
  723.     BPTR                    fl;
  724.     Object                *obj = NULL;
  725.  
  726.     if ( fl = Lock( filename, ACCESS_READ ) ) {
  727.  
  728.         if ( dt = ObtainDataTypeA( DTST_FILE, (APTR)fl, NULL ) ) {
  729.  
  730.             if ( dt->dtn_Header->dth_GroupID == GID_PICTURE ) {
  731.                 ReleaseDataType( dt );
  732.  
  733.                 /*** At this point we are sure that 'filename' is a picture */
  734.  
  735.                 /* get the picture object */
  736.                 if ( obj = NewDTObject( filename,
  737.                                         DTA_SourceType, DTST_FILE,
  738.                                         DTA_GroupID, GID_PICTURE,
  739.                                         PDTA_Remap, FALSE,
  740.                                         TAG_DONE) ) {
  741.  
  742.                     if ( GetDTAttrs( obj, PDTA_ColorRegisters, pt_cmap,
  743.                                               PDTA_NumColors, pt_ncolors ) != 2 ) {
  744.                         DisposeDTObject( obj );
  745.                         obj = NULL;
  746.                         *pt_cmap = NULL;
  747.                     }
  748.  
  749.                     DPUT(("ColorMap got: ncolors = %ld, cmap = %lx\n", (LONG) *pt_ncolors, (LONG) *pt_cmap ));
  750.  
  751.                 }
  752.  
  753.             }
  754.             else
  755.                 ReleaseDataType( dt );
  756.  
  757.         }
  758.  
  759.         UnLock( fl );
  760.     }
  761.  
  762.     return obj;
  763.  
  764. }
  765.  
  766. /*****************************************************************************/
  767.  
  768. void FreeFileColorMap( Object *obj, struct ClassBase *cb ) {
  769.  
  770.     DisposeDTObject( obj );
  771.  
  772. }
  773.  
  774.